package com.mgface.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wanyuxiang
 * @version 1.0
 * @project Java10Demo
 * @create 2018-08-14 13:47
 **/
public class Server {
    private static final ExecutorService exec = Executors.newFixedThreadPool(1);

    private static final ConcurrentHashMap<String,Class> serviceRegistry = new ConcurrentHashMap<>();

    public void register(Class cls,Class impl){
        serviceRegistry.putIfAbsent(cls.getName(),impl);
    }
    public void start(int port) throws IOException {
        ServerSocket server = new ServerSocket(port);
        System.out.println("服务启动...");
        while(true){

           final Socket socket = server.accept();
            exec.execute(()->{
                try {
                    try(ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream())){
                       String serviceName = input.readUTF();
                       String methodName = input.readUTF();
                       Class<?>[] parameterTypes = (Class<?>[])input.readObject();
                       Object[] args = (Object[])input.readObject();
                       Class<?> cls =  serviceRegistry.get(serviceName);
                       if (cls==null){
                           throw new ClassNotFoundException(serviceName+" 未找到！");
                       }
                       Method method = cls.getMethod(methodName,parameterTypes);
                       Object result =  method.invoke(cls.getDeclaredConstructor().newInstance(),args);
                        output.writeObject(result);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });
        }
    }
}
